package com.example.comment.service.impl;

import com.example.comment.pojo.Comment;
import com.example.comment.pojo.CommentRepay;
import com.example.comment.pojo.CommentRepayLike;
import com.example.comment.pojo.CommentRepayVo;
import com.example.comment.service.CommentRepayService;
import com.example.common.util.R;
import com.example.common.util.ResultCodeRecord;
import com.example.feignapi.user.UserClient;
import com.example.model.comment.dto.CommentRepayDto;
import com.example.model.comment.dto.CommentRepayLikeDto;
import com.example.model.comment.dto.CommentRepaySaveDto;
import com.example.model.user.pojo.User;
import com.example.utils.thread.UserThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class CommentRepayServiceImpl implements CommentRepayService {
    @Autowired
    private UserClient userClient;
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public Object getLoadCommentRepay(CommentRepayDto commentRepayDto) {
        // 1、检查参数
        if (commentRepayDto == null || commentRepayDto.getCommentId() == null) {
            return R.error(ResultCodeRecord.PARAM_INVALID).isFlag();
        }
        Integer size = 20;
        // 2、加载数据
        Query query = Query.query(Criteria.where("commentId").is(commentRepayDto.getCommentId()).and("createdTime").lt(commentRepayDto.getMinDate()));
        query.with(Sort.by(Sort.Direction.DESC, "createdTime")).limit(size);
        List< CommentRepay > commentRepayList = mongoTemplate.find(query, CommentRepay.class);
        // 3、数据封装返回
        // 3、1 用未登录
        User user = UserThreadLocal.getUser();
        if (user == null) {
            return R.ok("查询更多回复内容成功").data("commentRepayList", commentRepayList).isFlag();
        }

        // 3、2 用户已登录
        // 需要查询当前评论中哪些数据被点赞了
        List< String > idList = commentRepayList.stream().map(CommentRepay::getId).toList();
        Query query1 = Query.query(Criteria.where("commentRepayId").in(idList).and("authorId").is(user.getUserId()));
        List< CommentRepayLike > commentRepayLikeList = mongoTemplate.find(query1, CommentRepayLike.class);
        if (commentRepayLikeList == null || commentRepayLikeList.size() == 0) {
            return R.ok("查询更多回复内容成功").data("commentRepayList", commentRepayList).isFlag();
        }
        List< CommentRepayVo > commentRepayVoList = new ArrayList<>();
        for (CommentRepay commentRepay : commentRepayList) {
            CommentRepayVo commentRepayVo = new CommentRepayVo();
            BeanUtils.copyProperties(commentRepay, commentRepayVo);
            for (CommentRepayLike commentRepayLike : commentRepayLikeList) {
                if (commentRepay.getId().equals(commentRepayLike.getCommentRepayId())) {
                    commentRepayVo.setOperation((short) 0);
                    break;
                }
            }
            commentRepayVoList.add(commentRepayVo);
        }
        return commentRepayVoList;
    }

    @Override
    public boolean addCommentRepay(CommentRepaySaveDto commentRepaySaveDto) {
        // 1、检查参数
        if (commentRepaySaveDto == null || StringUtils.isBlank(commentRepaySaveDto.getContent()) || commentRepaySaveDto.getCommentId() == null) {
            return R.error(ResultCodeRecord.PARAM_INVALID).isFlag();
        }
        if (commentRepaySaveDto.getContent().length() > 140) {
            return R.error(ResultCodeRecord.PARAM_INVALID, "评论内容不能超过140字").isFlag();
        }

        // 1、检查参数
        if (commentRepaySaveDto == null || StringUtils.isBlank(commentRepaySaveDto.getContent()) || commentRepaySaveDto.getCommentId() == null) {
            return R.error(ResultCodeRecord.PARAM_INVALID).isFlag();
        }
        // 2、判断是否登录
        User user = UserThreadLocal.getUser();
        if (user == null) {
            return R.error(ResultCodeRecord.NEED_LOGIN).isFlag();
        }

        // 3、安全检查 自行实现
        // 4、保存评论
        User user1 = userClient.getUserByUserId(user.getUserId());
        if (user1 == null) {
            return R.error(ResultCodeRecord.PARAM_INVALID, "当前登录信息有误").isFlag();
        }
        CommentRepay commentRepay = new CommentRepay();
        commentRepay.setAuthorId(user.getUserId());
        commentRepay.setContent(commentRepaySaveDto.getContent());
        commentRepay.setCreatedTime(new Date());
        commentRepay.setCommentId(commentRepaySaveDto.getCommentId());
        commentRepay.setAuthorName(user1.getUserName());
        commentRepay.setUpdatedTime(new Date());
        commentRepay.setLikes(0);
        mongoTemplate.save(commentRepay);

        // 5、更新回复数量
        Comment comment = mongoTemplate.findById(commentRepaySaveDto.getCommentId(), Comment.class);
        if (comment != null) {
            comment.setReply(comment.getReply() + 1);
            mongoTemplate.save(comment);
        }
        return true;
    }

    @Override
    public boolean deleteCommentRepay(String commentRepayId) {
        // 1、检查参数
        if (StringUtils.isBlank(commentRepayId)) {
            return R.error(ResultCodeRecord.PARAM_INVALID).isFlag();
        }
        // 2、判断是否登录
        User user = UserThreadLocal.getUser();
        if (user == null) {
            return R.error(ResultCodeRecord.NEED_LOGIN).isFlag();
        }

        // 3、安全检查 自行实现
        // 4、超找要删除的评论回复
        CommentRepay commentRepay = mongoTemplate.findById(commentRepayId, CommentRepay.class);
        if (commentRepay == null) {
            return R.error(ResultCodeRecord.PARAM_INVALID, "指定的评论回复不存在").isFlag();
        }
        // 5、删除评论回复
        mongoTemplate.remove(commentRepay);

        // 6、更新评论的回复数量
        Query query = Query.query(Criteria.where("commentId").is(commentRepay.getCommentId()));
        long replyCount = mongoTemplate.count(query, CommentRepay.class);
        Comment comment = mongoTemplate.findById(commentRepay.getCommentId(), Comment.class);
        if (comment != null) {
            comment.setReply((int) replyCount);
            mongoTemplate.save(comment);
        }
        return true;
    }

    @Override
    public Object addCommentRepayLike(CommentRepayLikeDto commentRepayLikeDto) {
        // 1、检查参数
        if (commentRepayLikeDto == null || commentRepayLikeDto.getCommentRepayId() == null) {
            return R.error(ResultCodeRecord.PARAM_INVALID);
        }

        // 2、判断是否登录
        User user = UserThreadLocal.getUser();
        if (user == null) {
            return R.error(ResultCodeRecord.NEED_LOGIN);
        }

        // 3、获取评论回复
        CommentRepay commentRepay = mongoTemplate.findById(commentRepayLikeDto.getCommentRepayId(), CommentRepay.class);
        if (commentRepay == null) {
            return R.error(ResultCodeRecord.PARAM_INVALID, "指定的评论回复不存在");
        }
        // 4、点赞
        if (commentRepayLikeDto.getOperation() == 0) {
            // 更新评论点赞数量
            commentRepay.setLikes(commentRepay.getLikes() + 1);
            mongoTemplate.save(commentRepay);

            // 保存评论点赞数据
            CommentRepayLike commentRepayLike = new CommentRepayLike();
            commentRepayLike.setCommentRepayId(commentRepay.getId());
            commentRepayLike.setAuthorId(user.getUserId());
            mongoTemplate.save(commentRepayLike);
        } else {
            // 更新评论点赞数量
            int tmp = commentRepay.getLikes() - 1;
            tmp = tmp < 1 ? 0 : tmp;
            commentRepay.setLikes(tmp);
            mongoTemplate.save(commentRepay);

            // 删除评论点赞
            Query query = Query.query(Criteria.where("commentRepayId").is(commentRepay.getId()).and("authorId").is(user.getUserId()));
            mongoTemplate.remove(query, CommentRepayLike.class);
        }

        // 5、取消点赞
        Map< String, Object > map = new HashMap<>();
        map.put("likes", commentRepay.getLikes());
        return map;
    }
}
